/*   1:    */ package com.atomikos.datasource.xa;
/*   2:    */ 
/*   3:    */ import com.atomikos.datasource.RecoverableResource;
/*   4:    */ import com.atomikos.datasource.ResourceException;
/*   5:    */ import com.atomikos.datasource.ResourceTransaction;
/*   6:    */ import com.atomikos.datasource.TransactionalResource;
/*   7:    */ import com.atomikos.diagnostics.Console;
/*   8:    */ import com.atomikos.icatch.CompositeTransaction;
/*   9:    */ import com.atomikos.icatch.Participant;
/*  10:    */ import com.atomikos.icatch.RecoveryService;
/*  11:    */ import com.atomikos.icatch.SysException;
/*  12:    */ import com.atomikos.icatch.system.Configuration;
/*  13:    */ import com.atomikos.persistence.StateRecoveryManager;
/*  14:    */ import java.util.Enumeration;
/*  15:    */ import java.util.Hashtable;
/*  16:    */ import java.util.Stack;
/*  17:    */ import java.util.Vector;
/*  18:    */ import javax.transaction.xa.XAException;
/*  19:    */ import javax.transaction.xa.XAResource;
/*  20:    */ import javax.transaction.xa.Xid;
/*  21:    */ 
/*  22:    */ public abstract class XATransactionalResource
/*  23:    */   implements TransactionalResource
/*  24:    */ {
/*  25:    */   protected XAResource xares_;
/*  26:    */   protected String servername_;
/*  27:    */   protected Hashtable recoveryMap_;
/*  28:    */   protected Hashtable siblingmappers_;
/*  29:    */   protected XidFactory xidFact_;
/*  30:    */   private boolean closed_;
/*  31:    */   private boolean weakCompare_;
/*  32:    */   private boolean compareAlwaysTrue_;
/*  33:    */   private String branchIdentifier_;
/*  34:    */   
/*  35:    */   public XATransactionalResource(String servername)
/*  36:    */   {
/*  37:115 */     this.servername_ = servername;
/*  38:116 */     this.siblingmappers_ = new Hashtable();
/*  39:    */     
/*  40:118 */     String maxLong = "9223372036854775807";
/*  41:    */     
/*  42:120 */     String testName = servername + maxLong;
/*  43:121 */     if (testName.getBytes().length > 64) {
/*  44:122 */       throw new RuntimeException("Max length of resource name exceeded: should be less than " + (64 - maxLong.getBytes().length));
/*  45:    */     }
/*  46:124 */     this.xidFact_ = new DefaultXidFactory();
/*  47:125 */     this.closed_ = false;
/*  48:126 */     this.weakCompare_ = false;
/*  49:127 */     this.compareAlwaysTrue_ = false;
/*  50:128 */     this.branchIdentifier_ = servername;
/*  51:    */   }
/*  52:    */   
/*  53:    */   public XATransactionalResource(String servername, XidFactory factory)
/*  54:    */   {
/*  55:144 */     this(servername);
/*  56:145 */     this.xidFact_ = factory;
/*  57:    */   }
/*  58:    */   
/*  59:    */   protected abstract XAResource refreshXAConnection()
/*  60:    */     throws ResourceException;
/*  61:    */   
/*  62:    */   public XidFactory getXidFactory()
/*  63:    */   {
/*  64:176 */     return this.xidFact_;
/*  65:    */   }
/*  66:    */   
/*  67:    */   protected void printMsg(String msg, int level)
/*  68:    */   {
/*  69:    */     try
/*  70:    */     {
/*  71:182 */       Console console = Configuration.getConsole();
/*  72:183 */       if (console != null) {
/*  73:184 */         console.println(msg, level);
/*  74:    */       }
/*  75:    */     }
/*  76:    */     catch (Exception ignore) {}
/*  77:    */   }
/*  78:    */   
/*  79:    */   void removeSiblingMap(String root)
/*  80:    */   {
/*  81:192 */     synchronized (this.siblingmappers_)
/*  82:    */     {
/*  83:193 */       this.siblingmappers_.remove(root);
/*  84:    */     }
/*  85:    */   }
/*  86:    */   
/*  87:    */   SiblingMapper getSiblingMap(String root)
/*  88:    */   {
/*  89:200 */     synchronized (this.siblingmappers_)
/*  90:    */     {
/*  91:201 */       if (this.siblingmappers_.containsKey(root)) {
/*  92:202 */         return (SiblingMapper)this.siblingmappers_.get(root);
/*  93:    */       }
/*  94:204 */       SiblingMapper map = new SiblingMapper(this, root);
/*  95:205 */       this.siblingmappers_.put(root, map);
/*  96:206 */       return map;
/*  97:    */     }
/*  98:    */   }
/*  99:    */   
/* 100:    */   protected boolean needsRefresh()
/* 101:    */   {
/* 102:219 */     boolean ret = true;
/* 103:    */     try
/* 104:    */     {
/* 105:227 */       if (this.xares_ != null)
/* 106:    */       {
/* 107:228 */         this.xares_.isSameRM(this.xares_);
/* 108:229 */         ret = false;
/* 109:    */       }
/* 110:    */     }
/* 111:    */     catch (XAException xa)
/* 112:    */     {
/* 113:233 */       if (Configuration.isDebugLoggingEnabled()) {
/* 114:233 */         Configuration.logDebug(this.servername_ + ": XAResource needs refresh?", xa);
/* 115:    */       }
/* 116:    */     }
/* 117:237 */     return ret;
/* 118:    */   }
/* 119:    */   
/* 120:    */   public void useWeakCompare(boolean weakCompare)
/* 121:    */   {
/* 122:259 */     this.weakCompare_ = weakCompare;
/* 123:    */   }
/* 124:    */   
/* 125:    */   public boolean usesWeakCompare()
/* 126:    */   {
/* 127:278 */     return this.weakCompare_;
/* 128:    */   }
/* 129:    */   
/* 130:    */   public void setAcceptAllXAResources(boolean val)
/* 131:    */   {
/* 132:293 */     this.compareAlwaysTrue_ = val;
/* 133:    */   }
/* 134:    */   
/* 135:    */   public boolean acceptsAllXAResources()
/* 136:    */   {
/* 137:302 */     return this.compareAlwaysTrue_;
/* 138:    */   }
/* 139:    */   
/* 140:    */   public boolean usesXAResource(XAResource xares)
/* 141:    */   {
/* 142:317 */     if (acceptsAllXAResources()) {
/* 143:318 */       return true;
/* 144:    */     }
/* 145:320 */     XAResource xaresource = getXAResource();
/* 146:321 */     if (xaresource == null) {
/* 147:322 */       return false;
/* 148:    */     }
/* 149:325 */     boolean ret = false;
/* 150:327 */     if (!xares.getClass().getName().equals(xaresource.getClass().getName())) {
/* 151:333 */       ret = false;
/* 152:    */     } else {
/* 153:    */       try
/* 154:    */       {
/* 155:338 */         if (xares.isSameRM(xaresource)) {
/* 156:339 */           ret = true;
/* 157:340 */         } else if (usesWeakCompare()) {
/* 158:345 */           ret = true;
/* 159:    */         } else {
/* 160:347 */           Configuration.logDebug("XAResources claim to be different: " + xares + " and " + xaresource);
/* 161:    */         }
/* 162:    */       }
/* 163:    */       catch (XAException xe)
/* 164:    */       {
/* 165:352 */         Stack errors = new Stack();
/* 166:353 */         errors.push(xe);
/* 167:354 */         throw new SysException("Error in XAResource comparison: " + xe.getMessage(), errors);
/* 168:    */       }
/* 169:    */     }
/* 170:358 */     return ret;
/* 171:    */   }
/* 172:    */   
/* 173:    */   public synchronized XAResource getXAResource()
/* 174:    */   {
/* 175:370 */     if (needsRefresh())
/* 176:    */     {
/* 177:371 */       Configuration.logDebug(this.servername_ + ": refreshing XAResource...");
/* 178:    */       
/* 179:373 */       this.xares_ = refreshXAConnection();
/* 180:374 */       Configuration.logInfo(this.servername_ + ": refreshed XAResource");
/* 181:    */     }
/* 182:389 */     return this.xares_;
/* 183:    */   }
/* 184:    */   
/* 185:    */   public ResourceTransaction getResourceTransaction(CompositeTransaction ct)
/* 186:    */     throws ResourceException, IllegalStateException
/* 187:    */   {
/* 188:399 */     if (this.closed_) {
/* 189:400 */       throw new IllegalStateException("XATransactionResource already closed");
/* 190:    */     }
/* 191:405 */     if (ct == null) {
/* 192:406 */       return null;
/* 193:    */     }
/* 194:413 */     Stack lineage = ct.getLineage();
/* 195:414 */     String root = null;
/* 196:415 */     if ((lineage == null) || (lineage.isEmpty()))
/* 197:    */     {
/* 198:416 */       root = ct.getTid();
/* 199:    */     }
/* 200:    */     else
/* 201:    */     {
/* 202:418 */       Stack tmp = (Stack)lineage.clone();
/* 203:419 */       while (!tmp.isEmpty())
/* 204:    */       {
/* 205:420 */         CompositeTransaction next = (CompositeTransaction)tmp.pop();
/* 206:421 */         if (next.isRoot()) {
/* 207:422 */           root = next.getTid();
/* 208:    */         }
/* 209:    */       }
/* 210:    */     }
/* 211:425 */     return getSiblingMap(root).map(ct);
/* 212:    */   }
/* 213:    */   
/* 214:    */   private StateRecoveryManager getRecoveryManager()
/* 215:    */     throws ResourceException
/* 216:    */   {
/* 217:431 */     if (this.closed_) {
/* 218:432 */       throw new IllegalStateException("XATransactionResource already closed");
/* 219:    */     }
/* 220:437 */     return null;
/* 221:    */   }
/* 222:    */   
/* 223:    */   public String getName()
/* 224:    */   {
/* 225:446 */     return this.servername_;
/* 226:    */   }
/* 227:    */   
/* 228:    */   public void close()
/* 229:    */     throws ResourceException
/* 230:    */   {
/* 231:458 */     this.closed_ = true;
/* 232:    */   }
/* 233:    */   
/* 234:    */   public boolean isClosed()
/* 235:    */     throws ResourceException
/* 236:    */   {
/* 237:469 */     return this.closed_;
/* 238:    */   }
/* 239:    */   
/* 240:    */   public boolean isSameRM(RecoverableResource res)
/* 241:    */     throws ResourceException
/* 242:    */   {
/* 243:479 */     if ((res == null) || (!(res instanceof XATransactionalResource))) {
/* 244:480 */       return false;
/* 245:    */     }
/* 246:482 */     XATransactionalResource xatxres = (XATransactionalResource)res;
/* 247:483 */     if ((xatxres.servername_ == null) || (this.servername_ == null)) {
/* 248:484 */       return false;
/* 249:    */     }
/* 250:486 */     return xatxres.servername_.equals(this.servername_);
/* 251:    */   }
/* 252:    */   
/* 253:    */   public void setRecoveryService(RecoveryService recoveryService)
/* 254:    */     throws ResourceException
/* 255:    */   {
/* 256:498 */     if (recoveryService != null)
/* 257:    */     {
/* 258:499 */       if (Configuration.isDebugLoggingEnabled()) {
/* 259:499 */         Configuration.logDebug("Installing recovery service on resource " + getName());
/* 260:    */       }
/* 261:501 */       this.branchIdentifier_ = recoveryService.getName();
/* 262:    */       
/* 263:503 */       recoveryService.recover();
/* 264:    */     }
/* 265:    */   }
/* 266:    */   
/* 267:    */   public synchronized boolean recover(Participant participant)
/* 268:    */     throws ResourceException
/* 269:    */   {
/* 270:518 */     boolean recovered = true;
/* 271:519 */     if (this.closed_) {
/* 272:520 */       throw new IllegalStateException("XATransactionResource already closed");
/* 273:    */     }
/* 274:523 */     if (!(participant instanceof XAResourceTransaction)) {
/* 275:524 */       throw new ResourceException("Wrong argument class: " + participant.getClass().getName());
/* 276:    */     }
/* 277:526 */     XAResource xaresource = getXAResource();
/* 278:528 */     if (xaresource == null)
/* 279:    */     {
/* 280:529 */       Configuration.logWarning("XATransactionalResource " + getName() + ": XAResource is NULL!");
/* 281:    */       
/* 282:    */ 
/* 283:532 */       return false;
/* 284:    */     }
/* 285:535 */     XAResourceTransaction xarestx = (XAResourceTransaction)participant;
/* 286:537 */     if (this.recoveryMap_ == null) {
/* 287:538 */       recover();
/* 288:    */     }
/* 289:540 */     if (!this.recoveryMap_.containsKey(xarestx.getXid())) {
/* 290:544 */       recovered = false;
/* 291:    */     }
/* 292:551 */     if ((recovered) || (getName().equals(xarestx.getResourceName()))) {
/* 293:552 */       xarestx.setRecoveredXAResource(getXAResource());
/* 294:    */     }
/* 295:553 */     this.recoveryMap_.remove(xarestx.getXid());
/* 296:554 */     return recovered;
/* 297:    */   }
/* 298:    */   
/* 299:    */   protected void recover()
/* 300:    */     throws ResourceException
/* 301:    */   {
/* 302:567 */     this.recoveryMap_ = new Hashtable();
/* 303:568 */     Xid[] recoveredlist = null;
/* 304:569 */     int flags = 16777216;
/* 305:570 */     boolean done = false;
/* 306:571 */     Stack errors = new Stack();
/* 307:572 */     Vector recoveredXids = new Vector();
/* 308:    */     
/* 309:    */ 
/* 310:    */ 
/* 311:    */ 
/* 312:    */ 
/* 313:    */ 
/* 314:    */ 
/* 315:580 */     printMsg("recovery initiated for resource " + getName() + " with branchIdentifier " + this.branchIdentifier_, 3);
/* 316:    */     do
/* 317:    */     {
/* 318:    */       try
/* 319:    */       {
/* 320:585 */         recoveredlist = getXAResource().recover(flags);
/* 321:    */       }
/* 322:    */       catch (NullPointerException ora)
/* 323:    */       {
/* 324:588 */         if (getXAResource().getClass().getName().toLowerCase().indexOf("oracle") >= 0) {
/* 325:589 */           printMsg("ORACLE NOT CONFIGURED FOR XA? PLEASE CONTACT YOUR DBA TO FIX THIS...", 1);
/* 326:    */         }
/* 327:591 */         throw ora;
/* 328:    */       }
/* 329:    */       catch (XAException xaerr)
/* 330:    */       {
/* 331:594 */         Configuration.logWarning("Error in recovery", xaerr);
/* 332:595 */         errors.push(xaerr);
/* 333:596 */         throw new ResourceException("Error in recovery", errors);
/* 334:    */       }
/* 335:598 */       flags = 0;
/* 336:599 */       done = (recoveredlist == null) || (recoveredlist.length == 0);
/* 337:600 */       if (!done)
/* 338:    */       {
/* 339:608 */         done = true;
/* 340:609 */         for (int i = 0; i < recoveredlist.length; i++)
/* 341:    */         {
/* 342:611 */           Xid xid = new XID(recoveredlist[i]);
/* 343:614 */           if (!recoveredXids.contains(xid))
/* 344:    */           {
/* 345:617 */             printMsg("Resource " + this.servername_ + " inspecting XID: " + xid, 2);
/* 346:    */             
/* 347:619 */             recoveredXids.addElement(xid);
/* 348:620 */             done = false;
/* 349:    */             
/* 350:    */ 
/* 351:623 */             String branch = new String(recoveredlist[i].getBranchQualifier());
/* 352:625 */             if (branch.startsWith(this.branchIdentifier_))
/* 353:    */             {
/* 354:626 */               this.recoveryMap_.put(xid, new Object());
/* 355:627 */               printMsg("Resource " + this.servername_ + " recovering XID: " + xid, 2);
/* 356:    */             }
/* 357:    */             else
/* 358:    */             {
/* 359:630 */               printMsg("Resource " + this.servername_ + ": XID " + xid + " with branch " + branch + " is not under my responsibility", 2);
/* 360:    */             }
/* 361:    */           }
/* 362:    */         }
/* 363:    */       }
/* 364:638 */     } while (!done);
/* 365:641 */     recoveredXids = null;
/* 366:    */   }
/* 367:    */   
/* 368:    */   public void endRecovery()
/* 369:    */     throws ResourceException
/* 370:    */   {
/* 371:651 */     if (this.closed_) {
/* 372:652 */       throw new IllegalStateException("XATransactionResource already closed");
/* 373:    */     }
/* 374:655 */     XAResource xaresource = getXAResource();
/* 375:662 */     if (xaresource == null) {
/* 376:663 */       return;
/* 377:    */     }
/* 378:669 */     if (this.recoveryMap_ == null) {
/* 379:670 */       recover();
/* 380:    */     }
/* 381:672 */     Enumeration toAbortList = this.recoveryMap_.keys();
/* 382:673 */     while (toAbortList.hasMoreElements())
/* 383:    */     {
/* 384:674 */       XID xid = (XID)toAbortList.nextElement();
/* 385:    */       try
/* 386:    */       {
/* 387:676 */         xaresource.rollback(xid);
/* 388:    */         
/* 389:678 */         printMsg("XAResource.rollback ( " + xid + " ) called " + "on resource " + this.servername_, 2);
/* 390:    */       }
/* 391:    */       catch (XAException xaerr) {}
/* 392:    */     }
/* 393:687 */     this.recoveryMap_ = null;
/* 394:    */     
/* 395:689 */     printMsg("endRecovery() done for resource " + getName(), 3);
/* 396:    */   }
/* 397:    */   
/* 398:    */   public void setXidFactory(XidFactory factory)
/* 399:    */   {
/* 400:700 */     this.xidFact_ = factory;
/* 401:    */   }
/* 402:    */   
/* 403:    */   protected Xid createXid(String tid)
/* 404:    */   {
/* 405:715 */     return getXidFactory().createXid(tid, this.branchIdentifier_);
/* 406:    */   }
/* 407:    */ }


/* Location:           C:\myfile\mysoft\apache-maven-3.5.0-bin\apache-maven-3.5.0\myrep\com\atomikos\transactions-jta\3.7.0\transactions-jta-3.7.0.jar
 * Qualified Name:     com.atomikos.datasource.xa.XATransactionalResource
 * JD-Core Version:    0.7.0.1
 */